import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:lib_common/components/dialog/ntt_input_dialog.dart';
import 'package:lib_common/components/dialog/ntt_selected_dialog.dart';
import 'package:lib_common/components/dialog/ntt_standard_dialog.dart';

class NttDialogUtils {
  static NttDialogUtils? _instance;

  static NttDialogUtils get instance {
    _instance ??= NttDialogUtils._();
    return _instance!;
  }

  NttDialogUtils._();

  /// 是否正在显示弹窗
  bool isShowDialog = false;

  /// 初始化
  /// w / h 设计稿中设备的尺寸(单位方便,建议dp,但在使用过程中必须保持一致)
  ///
  void init(BuildContext context, double w, double h) {
    debugPrint("Init context: $context");
    ScreenUtil.init(context, designSize: Size(w, h));
  }

  /// 检测上下文
  // void detectionContext() {
  //   if (_context == null) {
  //     throw "没有初始化";
  //   }
  // }

  /// 显示普通确认弹窗
  /// [title] 标题
  /// [content] 内容
  /// [cancelText] 左边的按钮文本
  /// [confirmText] 右边的按钮文本
  /// [onCancel] 取消按钮点击事件
  /// [onConfirm] 确认按钮点击事件
  /// [barrierDismissible] 是否需要点击空白区域关闭弹窗
  /// [barrierColor] 蒙层背景色
  void showStandardDialog({
    required BuildContext context,
    required String title,
    String? content,
    TextSpan? contentSpan,
    required String cancelText,
    required String confirmText,
    required VoidCallback onCancel,
    required VoidCallback onConfirm,
    bool barrierDismissible = false,
    Color? barrierColor,
  }) async {
    // detectionContext();
    isShowDialog = true;
    showDialog(
        context: context,
        useSafeArea: false,
        barrierColor: barrierColor,
        barrierDismissible: barrierDismissible,
        builder: (BuildContext context) {
          return NttStandardDialog(
            title: title,
            content: content,
            contentSpan: contentSpan,
            leftBtnTxt: cancelText,
            rightBtnTxt: confirmText,
          );
        }).then((value) {
      debugPrint('[showStandardDialog] value -> $value');
      isShowDialog = false;
      if (value == true) {
        onConfirm.call();
      } else {
        onCancel.call();
      }
    });
  }

  /// 显示输入弹窗
  /// [title] 顶部标题
  /// [cancelText] 左边的按钮文本
  /// [confirmText] 右边的按钮文本
  /// [onCancel] 取消按钮点击事件
  /// [onConfirm] 确认按钮点击事件
  /// [barrierDismissible] 是否需要点击空白区域关闭弹窗
  /// [barrierColor] 蒙层背景色
  /// [text] 弹出弹窗时的默认输入文本
  /// [hintText] 提示文本
  /// [inputType] 输入框类型
  /// [textInputAction] 输入框动作类型
  void showInputDialog({
    required BuildContext context,
    required String title,
    required String cancelText,
    required String confirmText,
    VoidCallback? onCancel,
    Function(String text)? onConfirm,
    bool barrierDismissible = false,
    Color? barrierColor,
    String? text,
    String? hintText,
    TextInputType? inputType,
    TextInputAction? textInputAction,
    bool resizeToAvoidBottomInset = true,
    int? maxLength,
  }) {
    // detectionContext();
    isShowDialog = true;
    showDialog(
        context: context,
        useSafeArea: false,
        barrierColor: barrierColor,
        barrierDismissible: barrierDismissible,
        builder: (BuildContext context) {
          return NttInputDialog(
            title: title,
            leftBtnTxt: cancelText,
            rightBtnTxt: confirmText,
            barrierDismissible: barrierDismissible,
            text: text,
            hintText: hintText ?? "请输入内容…",
            inputType: inputType ?? TextInputType.visiblePassword,
            textInputAction: textInputAction ?? TextInputAction.search,
            resizeToAvoidBottomInset: resizeToAvoidBottomInset,
            maxLength: maxLength,
          );
        }).then((value) {
      isShowDialog = false;
      debugPrint('[showInputDialog] value -> $value');
      if (value is Map) {
        onConfirm?.call(value['text']);
      } else {
        onCancel?.call();
      }
    });
  }

  /// 显示选择弹窗
  /// [title] 顶部标题
  /// [datas] 数据源
  /// [defaultSelects] 默认选中的item
  /// [buttonText] 按钮文本
  /// [barrierColor] 蒙层背景色
  /// [barrierDismissible] 是否需要点击空白区域关闭弹窗
  /// [isSingleSelect] 是否单选 单选时 defaultSelects 只能传一个 传多个也只会选第一个
  /// [onCancel] 取消按钮点击事件
  /// [onConfirm] 确认按钮点击事件 (返回选中的item数据)
  void showSelectedDialog({
    required BuildContext context,
    required String title,
    required List<String> datas,
    List<String>? defaultSelects,
    String? buttonText,
    Color? barrierColor,
    bool barrierDismissible = false,
    bool isSingleSelect = false,
    VoidCallback? onCancel,
    Function(List<String> selects)? onConfirm,
  }) {
    // detectionContext();
    isShowDialog = true;
    showDialog(
        context: context,
        useSafeArea: false,
        barrierColor: barrierColor,
        barrierDismissible: barrierDismissible,
        builder: (BuildContext context) {
          return NttSelectedDialog(
            title: title,
            datas: datas,
            defaultSelects: defaultSelects,
            buttonText: buttonText,
            isSingleSelect: isSingleSelect,
          );
        }).then((value) {
      isShowDialog = false;
      debugPrint('[showSelectedDialog] value -> $value');
      if (value is Map) {
        onConfirm?.call(value['selects']);
      } else {
        onCancel?.call();
      }
    });
  }

  /// 显示自定义弹窗
  /// [builder] 需要显示的组件
  /// [barrierDismissible] 是否需要点击空白区域关闭弹窗
  /// [barrierColor] 背景颜色
  /// [barrierLabel]
  /// [useSafeArea] 是否使用安全区域
  /// [useRootNavigator] 是否使用根路由
  /// [routeSettings]
  /// [anchorPoint]
  /// [traversalEdgeBehavior]
  /// [onCallback] 回调 建议使用函数式 如：onCallback：onDialogCallback
  /// 而不是使用 onCallback: (value) => print(value), 使用 onCallback: (value) => print(value) 时闭包（closures）会捕获并持有其作用域中的所有变量。
  /// 这意味着 onCallback 闭包会捕获并持有 context 和其他外部变量，导致这些变量无法被释放。
  void showNttDialog({
    required BuildContext context,
    required WidgetBuilder builder,
    bool barrierDismissible = false,
    Color? barrierColor,
    String? barrierLabel,
    bool useSafeArea = false,
    bool useRootNavigator = true,
    RouteSettings? routeSettings,
    Offset? anchorPoint,
    TraversalEdgeBehavior? traversalEdgeBehavior,
    Function(dynamic value)? onCallback,
  }) {
    // detectionContext();
    isShowDialog = true;
    showDialog(
      context: context,
      barrierColor: barrierColor,
      barrierLabel: barrierLabel,
      useSafeArea: useSafeArea,
      useRootNavigator: useRootNavigator,
      barrierDismissible: barrierDismissible,
      routeSettings: routeSettings,
      anchorPoint: anchorPoint,
      traversalEdgeBehavior: traversalEdgeBehavior,
      builder: builder,
    ).then((value) {
      isShowDialog = false;
      onCallback?.call(value);
    });
  }
}
